#include "Common/Item/ItemMgr.h"
#include "base/core/gamemath.h"
#include "base/core/log.h"
#include "base/core/random.h"
#include "base/core/com_define.h"
#include "Common/TableData/RoleBornCfg.h"
#include "Common/Utility/AccountUtility.h"
#include "Common/TableData/FunctionunlockFunctionUnlockCfg.h"
#include "Common/TableData/BoxDropCfg.h"
#include "Common/TableData/BoxSonCfg.h"
#include "Common/TableData/DropDropCfg.h"
#include "Common/TableDataEx/DropCfg.h"
#include "Common/DropDefine.h"

ItemMgr::ItemMgr()
{
	m_pItemPool = nullptr;
	m_pEquipPool = nullptr;
	memset(m_CompareFunc, 0, sizeof(m_CompareFunc));
	m_CompareFunc[EPackageLabel_sundry] = CompareSundryFunc;
	m_CompareFunc[EPackageLabel_material] = CompareMaterialFunc;
	m_CompareFunc[EPackageLabel_task] = CompareTaskFunc;
	m_CompareFunc[EPackageLabel_equip] = CompareEquipFunc;
	m_CompareDupFunc = CompareDuplicateFunc;
}

ItemMgr::~ItemMgr()
{

}

bool ItemMgr::Init()
{
	m_pItemPool = new ObjectPool<CItem>(100,false);
	m_pEquipPool = new ObjectPool<CEquip>(100,false);
	if (nullptr == m_pEquipPool || nullptr == m_pItemPool)
	{
		return false;
	}

	m_openLelMap.clear();
	const FunctionunlockFunctionUnlockCfgInfo * pStrenthOpenLevel = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_EQUIP_STRENGER);
	m_openLelMap[FunctionUnlock_ID_TYPE_EQUIP_STRENGER] = (pStrenthOpenLevel == nullptr) ? 0xff : pStrenthOpenLevel->unlockLevel;
	const FunctionunlockFunctionUnlockCfgInfo * pRefineOpenLevel = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_EQUIP_REFINE);
	m_openLelMap[FunctionUnlock_ID_TYPE_EQUIP_REFINE] = (pRefineOpenLevel == nullptr) ? 0xff : pRefineOpenLevel->unlockLevel;
	const FunctionunlockFunctionUnlockCfgInfo * pInlayOpenLevel = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_EQUIP_INLAY);
	m_openLelMap[FunctionUnlock_ID_TYPE_EQUIP_INLAY] = (pInlayOpenLevel == nullptr) ? 0xff : pInlayOpenLevel->unlockLevel;
	const FunctionunlockFunctionUnlockCfgInfo * pRuneOpenLevel = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_EQUIP_RUNE);
	m_openLelMap[FunctionUnlock_ID_TYPE_EQUIP_RUNE] = (pRuneOpenLevel == nullptr) ? 0xff : pRuneOpenLevel->unlockLevel;
	const FunctionunlockFunctionUnlockCfgInfo * pResolveOpenLevel = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_EQUIP_RESOLVE);
	m_openLelMap[FunctionUnlock_ID_TYPE_EQUIP_RESOLVE] = (pResolveOpenLevel == nullptr) ? 0xff : pResolveOpenLevel->unlockLevel;

	return true;
}

void ItemMgr::UnInit()
{
	MMO_DELETE(m_pItemPool);
	MMO_DELETE(m_pEquipPool);
	m_openLelMap.clear();
}


//获取标签页排序比较函数指针
CompareFunc *ItemMgr::GetCompareFunc(uint8_t byLabel)
{
	if (byLabel > EPackageLabel_none && byLabel < EPackageLabel_limit)
	{
		return &m_CompareFunc[byLabel];
	}
	return nullptr;
}

//获取副本比较函数
CompareDupFunc *ItemMgr::GetDupFunc()
{
	return &m_CompareDupFunc;
}

bool ItemMgr::CompareSundryFunc(CItemBase *pItemA, CItemBase *pItemB)
{
	//按材料物品品质降序
	//同品质按材料物品ID降序
	//相同ID的物品、装备，绑定状态不同（未绑定、已绑定），已绑定的排在前面，未绑定的排在后面
	//藏宝图物品按区域ID降序

	if (nullptr == pItemA || nullptr == pItemB)
	{
		return false;
	}
	const ItemItemCfgInfo *pItemCfgA = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemA->GetItemID());
	const ItemItemCfgInfo *pItemCfgB = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemB->GetItemID());
	if (nullptr == pItemCfgA || nullptr == pItemCfgB)
	{
		return false;
	}
	if (pItemCfgA->itemQuality == pItemCfgB->itemQuality)
	{
		if (pItemCfgA->id == pItemCfgB->id)
		{
			if (pItemA->GetBind() == pItemB->GetBind())
			{
				return pItemA->GetAreaId() > pItemB->GetAreaId();
			}
			return pItemA->GetBind() > pItemB->GetBind();			
		}
		return pItemCfgA->id > pItemCfgB->id;
	}

	return pItemCfgA->itemQuality > pItemCfgB->itemQuality;
}

bool ItemMgr::CompareMaterialFunc(CItemBase *pItemA, CItemBase *pItemB)
{
	/*
		按物品品质降序
		同品质按物品功能ID升序
		同功能按物品ID降序
		相同ID的物品、装备，绑定状态不同（未绑定、已绑定），已绑定的排在前面，未绑定的排在后面
	
	*/
	if (nullptr == pItemA || nullptr == pItemB)
	{
		return false;
	}
	const ItemItemCfgInfo *pItemCfgA = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemA->GetItemID());
	const ItemItemCfgInfo *pItemCfgB = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemB->GetItemID());
	if (nullptr == pItemCfgA || nullptr == pItemCfgB)
	{
		return false;
	}
	if (pItemCfgA->itemQuality == pItemCfgB->itemQuality)
	{
		if (pItemCfgA->functionType == pItemCfgB->functionType)
		{
			if (pItemCfgA->id == pItemCfgB->id)
			{
				return pItemA->GetBind() < pItemB->GetBind();
			}
			return pItemCfgA->id > pItemCfgB->id;
		}

		return pItemCfgA->functionType < pItemCfgB->functionType;
	}

	return pItemCfgA->itemQuality > pItemCfgB->itemQuality;

}

bool ItemMgr::CompareTaskFunc(CItemBase *pItemA, CItemBase *pItemB)
{
	//按物品ID降序
	//相同ID的物品、装备，绑定状态不同（未绑定、已绑定），已绑定的排在前面，未绑定的排在后面
	if (nullptr == pItemA || nullptr == pItemB)
	{
		return false;
	}
	if (pItemA->GetItemID() == pItemB->GetItemID())
	{
		return pItemA->GetBind() > pItemB->GetBind();
	}

	return pItemA->GetItemID() > pItemB->GetItemID();
}
bool ItemMgr::CompareEquipFunc(CItemBase *pItemA, CItemBase *pItemB)
{
	//装备
	//装备品质降序
	//同品质按部位编号降序
	//同部位按战力值降序
	//同战力按装备ID降序
	//相同ID的物品、装备，绑定状态不同（未绑定、已绑定），已绑定的排在前面，未绑定的排在后面

	/*
	 神装>时装（解锁物品）>装备
	 按装备品质降序
	 同品质按部位编号降序
	 同部位按增加战力值降序
	 同战力按装备ID降序
	 相同ID的物品、装备，绑定状态不同（未绑定、已绑定），已绑定的排在前面，未绑定的排在后面

	*/

	if (nullptr == pItemA || nullptr == pItemB)
	{
		return false;
	}
	//时装解锁物品配置在物品表，所以这里 pItemA 和pItemB 都有可能是时装解锁物品
	int8_t itypeA = 0; // 0 普通物品，1 时装解锁物品，2 神装装备
	int32_t qualityA = 0;
	int32_t positionA = 0;
	uint32_t itemIdA = pItemA->GetItemID();

	int8_t itypeB = 0;
	int32_t qualityB = 0;
	int32_t positionB = 0;
	uint32_t itemIdB = pItemB->GetItemID();
	//
	if (EItemType_equip == pItemA->GetType())
	{
		const EquipEquipCfgInfo *pItemCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItemA->GetItemID());
		if (nullptr == pItemCfg)
		{
			return false;
		}
		if (2 == pItemCfg->gold) //1为普通战斗装，2为神装
		{
			itypeA = 2;
		}
		positionA = pItemCfg->position;
		qualityA = pItemCfg->quality;
	}
	else
	{
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemA->GetItemID());
		if (nullptr == pItemCfg)
		{
			return false;
		}
		if (pItemCfg->functionType != (int32_t)EItemFuncType::EItemFuncType_Fashion)
		{
			return false;
		}
		itypeA = 1;
	}

	if (EItemType_equip == pItemB->GetType())
	{
		const EquipEquipCfgInfo *pItemCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItemB->GetItemID());
		if (nullptr == pItemCfg)
		{
			return false;
		}
		if (2 == pItemCfg->gold) //1为普通战斗装，2为神装
		{
			itypeB = 2;
		}
		positionB = pItemCfg->position;
		qualityB = pItemCfg->quality;
	}
	else
	{
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemB->GetItemID());
		if (nullptr == pItemCfg)
		{
			return false;
		}
		if (pItemCfg->functionType != (int32_t)EItemFuncType::EItemFuncType_Fashion)
		{
			return false;
		}
		itypeB = 1;
	}
	
	if (itypeA == itypeB)
	{
		if (qualityA == qualityB)
		{
			if (positionA == positionB)
			{
				if (pItemA->GetFight() == pItemB->GetFight())
				{
					//pItemA->GetItemID() > pItemB->GetItemID();
					return itemIdA > itemIdB;
				}
				return pItemA->GetFight() > pItemB->GetFight();
			}
			return positionA > positionB;
		}
		return qualityA > qualityB;
	}
	return itypeA > itypeB;
}


//副本拾取物品排序
bool ItemMgr::CompareDuplicateFunc(const ItemProtoInfo &protoA, const ItemProtoInfo &protoB)
{
	int32_t yjRuneFlagA = 0;
	int32_t dkRuneFlagA = 0;
	int32_t equipFlagA = 0;
	int32_t reelFlagA = 0;
	int32_t stoneFlagA = 0;
	int32_t gridFlagA = 0;
	int32_t refineFlagA = 0;
	int32_t medicineFlagA = 0;
	//
	int32_t yjRuneFlagB = 0;
	int32_t dkRuneFlagB = 0;
	int32_t equipFlagB = 0;
	int32_t reelFlagB = 0;
	int32_t stoneFlagB = 0;
	int32_t gridFlagB = 0;
	int32_t refineFlagB = 0;
	int32_t medicineFlagB = 0;
	//
	const ItemItemCfgInfo *pItemCfgA = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoA.item_id());
	if (nullptr != pItemCfgA)
	{
		if (pItemCfgA->subType >= (int32_t)EItemSubType::EItemSubType_yk_rune_begin && pItemCfgA->subType <= (int32_t)EItemSubType::EItemSubType_yk_rune_end)
		{
			yjRuneFlagA = 1;
		}
		else if (pItemCfgA->subType >= (int32_t)EItemSubType::EItemSubType_dy_rune_begin && pItemCfgA->subType <= (int32_t)EItemSubType::EItemSubType_dy_rune_end)
		{
			dkRuneFlagA = 1;
		}
		else if ((int32_t)EItemSubType::EItemSubType_Equip_materials_equip_reel == pItemCfgA->subType)
		{
			reelFlagA = 1;
		}
		else if (pItemCfgA->subType >= (int32_t)EItemSubType::EItemSubType_stone_begin && pItemCfgA->subType <= (int32_t)EItemSubType::EItemSubType_stone_end)
		{
			stoneFlagA = 1;
		}
		else if ((int32_t)EItemSubType::EItemSubType_strenth_materials_godgrid_stone == pItemCfgA->subType)
		{
			gridFlagA = 1;
		}
		else if (pItemCfgA->subType >= (int32_t)EItemSubType::EItemSubType_jl_materials_begin && pItemCfgA->subType <= (int32_t)EItemSubType::EItemSubType_jl_materials_end)
		{
			refineFlagA = 1;
		}
		else if (pItemCfgA->subType >= (int32_t)EItemSubType::EItemSubType_drug_begin && pItemCfgA->subType <= (int32_t)EItemSubType::EItemSubType_drug_end)
		{
			medicineFlagA = 1;
		}
	}
	else
	{
		const EquipEquipCfgInfo *pEquipCfgA = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(protoA.item_id());
		if (nullptr != pEquipCfgA)
		{
			equipFlagA = 1;
		}
	}

	//
	const ItemItemCfgInfo *pItemCfgB = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoB.item_id());
	if (nullptr != pItemCfgB)
	{
		if (pItemCfgB->subType >= (int32_t)EItemSubType::EItemSubType_yk_rune_begin && pItemCfgB->subType <= (int32_t)EItemSubType::EItemSubType_yk_rune_end)
		{
			yjRuneFlagB = 1;
		}
		else if (pItemCfgB->subType >= (int32_t)EItemSubType::EItemSubType_dy_rune_begin && pItemCfgB->subType <= (int32_t)EItemSubType::EItemSubType_dy_rune_end)
		{
			dkRuneFlagB = 1;
		}
		else if ((int32_t)EItemSubType::EItemSubType_Equip_materials_equip_reel == pItemCfgB->subType)
		{
			reelFlagB = 1;
		}
		else if (pItemCfgB->subType >= (int32_t)EItemSubType::EItemSubType_stone_begin && pItemCfgB->subType <= (int32_t)EItemSubType::EItemSubType_stone_end)
		{
			stoneFlagB = 1;
		}
		else if ((int32_t)EItemSubType::EItemSubType_strenth_materials_godgrid_stone == pItemCfgB->subType)
		{
			gridFlagB = 1;
		}
		else if (pItemCfgB->subType >= (int32_t)EItemSubType::EItemSubType_jl_materials_begin && pItemCfgB->subType <= (int32_t)EItemSubType::EItemSubType_jl_materials_end)
		{
			refineFlagB = 1;
		}
		else if (pItemCfgB->subType >= (int32_t)EItemSubType::EItemSubType_drug_begin && pItemCfgB->subType <= (int32_t)EItemSubType::EItemSubType_drug_end)
		{
			medicineFlagB = 1;
		}
	}
	else
	{
		const EquipEquipCfgInfo *pEquipCfgB = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(protoB.item_id());
		if (nullptr != pEquipCfgB)
		{
			equipFlagB = 1;
		}
	}
	
	/*
	排序优先级：印记（subType： 71,72,73,74,75）->
	雕文（subType：51,52,53,54,55）→
	装备道具→
	装备卷轴（subType：501）→
	宝石（subType：27,28,35,36,37,38）→
	神格晶石（subType：101）→
	精炼石（subType：151）→
	药水（subType：1）
	*/

	if (yjRuneFlagA == yjRuneFlagB)
	{
		if (dkRuneFlagA == dkRuneFlagB)
		{
			if (equipFlagA == equipFlagB)
			{
				if (reelFlagA == reelFlagB)
				{
					if (stoneFlagA == stoneFlagB)
					{
						if (gridFlagA == gridFlagB)
						{
							if (refineFlagA == refineFlagB)
							{
								return medicineFlagA > medicineFlagB;
							}
							return refineFlagA > refineFlagB;
						}
						return gridFlagA > gridFlagB;
					}
					return stoneFlagA > stoneFlagB;
				}
				return reelFlagA > reelFlagB;
			}
			return equipFlagA > equipFlagB;
		}
		return dkRuneFlagA > dkRuneFlagB;
	}
	return yjRuneFlagA > yjRuneFlagB;
}

CItemBase *ItemMgr::MakeItemObj(uint8_t byType)
{
	CItemBase *pItem = nullptr;
	switch (byType)
	{
	case EItemType_equip:
		{
			pItem = m_pEquipPool->MallocObj();
		}
		break;
	case EItemType_common:
		{
			pItem = m_pItemPool->MallocObj();
		}
		break;
	default:
		break;
	}

	return pItem;
}

bool ItemMgr::FreeItemObj(CItemBase *pItemObj)
{
	if (nullptr == pItemObj)
	{
		return false;
	}
	uint8_t byType = pItemObj->GetType();
	switch (byType)
	{
	case EItemType_equip:
		{
			m_pEquipPool->FreeObj((CEquip*)pItemObj);
		}
		break;
	case EItemType_common:
		{
			m_pItemPool->FreeObj((CItem*)pItemObj);
		}
		break;	
	default:
		{
			MMOLOG_FMT_ERROR("[logic] ItemMgr::FreeItemObj... unkown typle....byType:%d ", byType);
			MMO_DELETE(pItemObj);			
		}
		break;
	}

	return true;
}
//创建物品
bool ItemMgr::CreateItem(LIST_ITEM &lstItem, VEC_PACKAGE_ITEM &vecItems, SItemCond &itemCond, bool bMerge /*= true*/)
{
	if (!ValidInitAttrType(itemCond.inittype))
	{
		return false;
	}
	if (lstItem.size() <= 0)
	{
		return true;
	}
	LIST_ITEM lstOutItem;
	lstOutItem.clear();
	if (bMerge)
	{
		MergeItem(lstItem, lstOutItem);
	}
	else
	{
		lstOutItem = lstItem;
	}
	LIST_ITEM::iterator iter = lstOutItem.begin();
	for (; iter != lstOutItem.end(); ++iter)
	{
		SItem &item = (*iter);
		int8_t byType = EItemType_common;
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(item.nItemID);
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(item.nItemID);
			if (nullptr == pEquipCfg)
			{
				continue;
			}
			byType = EItemType_equip;
		}
		CItemBase *pItemObj = MakeItemObj(byType);
		if (nullptr == pItemObj)
		{
			continue;
		}
		if (!pItemObj->Init(0, item.nItemID, itemCond, item.nNum, item.byBind))
		{
			FreeItemObj(pItemObj);
			continue;
		}
		vecItems.push_back(pItemObj);
	}
	return true;
}
//
bool ItemMgr::CreateItem(LIST_ITEM &lstItem, VEC_ITEM_PROTO_EX &vecProtoEx, SItemCond &itemCond, bool bMerge /*= true*/)
{
	VEC_PACKAGE_ITEM vecItems;
	vecItems.clear();
	if (!CreateItem(lstItem, vecItems, itemCond,bMerge))
	{
		return false;
	}
	VEC_PACKAGE_ITEM::iterator iter = vecItems.begin();
	while (iter != vecItems.end())
	{
		CItemBase *pItem = (*iter);
		ItemProtoInfo proto;
		if (SetItemProtoInfo(pItem, &proto))
		{
			vecProtoEx.push_back(proto);
		}
		iter = vecItems.erase(iter);
		FreeItemObj(pItem);
	}
	return true;
}
//创建物品
bool ItemMgr::CreateItem(VEC_ITEM_PROTO &vecProtoItems, VEC_PACKAGE_ITEM &vecItems)
{
	VEC_ITEM_PROTO_EX vecProtoItemEx;
	vecProtoItemEx.clear();
	VEC_ITEM_PROTO::iterator iter = vecProtoItems.begin();
	for (; iter != vecProtoItems.end(); ++iter)
	{
		ItemProtoInfo *proto = (*iter);
		vecProtoItemEx.push_back(*proto);
	}
	return CreateItem(vecProtoItemEx, vecItems);
}
//创建物品
bool ItemMgr::CreateItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx, VEC_PACKAGE_ITEM &vecItems)
{
	if (!CheckItem(vecProtoItemsEx))
	{
		return false;
	}
	VEC_ITEM_PROTO_EX::iterator iter = vecProtoItemsEx.begin();
	for (; iter != vecProtoItemsEx.end(); ++iter)
	{
		ItemProtoInfo &protoItem = (*iter);
		int8_t byType = EItemType_common;
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoItem.item_id());
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(protoItem.item_id());
			if (nullptr == pEquipCfg)
			{
				continue;
			}
			byType = EItemType_equip;
		}

		CItemBase *pItemObj = MakeItemObj(byType);
		if (nullptr == pItemObj)
		{
			continue;
		}
		if (!pItemObj->SetItemProto(protoItem))
		{
			FreeItemObj(pItemObj);
			continue;
		}
		vecItems.push_back(pItemObj);
	}
	return true;
}
//创建掉落物品
bool ItemMgr::CreateDropItem(uint32_t nDropID, VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecDropGold, SItemCond &itemCond, int32_t itemReduce /*= DROP_RAND_BASE_NUM*/, int32_t goldReduce /*= DROP_RAND_BASE_NUM*/)
{
	const DropDropCfgInfo *pDropCfg = g_GetDropDropCfgTable()->GetDropDropCfgInfo(nDropID);
	if (nullptr == pDropCfg)
	{
		return false;
	}
	//随机物品
	LIST_ITEM lstItem;
	lstItem.clear();
	const VecSDropGroupCfg *pVecDropItemGroupCfg = g_GetDropCfgMgr()->GetDropItemGroupCfg(nDropID);
	if (nullptr != pVecDropItemGroupCfg)
	{
		VecSDropGroupCfg::const_iterator iterGroup = pVecDropItemGroupCfg->begin();
		for (; iterGroup != pVecDropItemGroupCfg->end(); ++iterGroup)
		{
			const VecSDropItemCfg  &vecGroupItem = (*iterGroup);
			if (vecGroupItem.size() <= 0)
			{
				continue;
			}
			int32_t randRate = Random(DROP_RAND_BASE_NUM + 1); // 0 - DROP_RAND_BASE_NUM
			int32_t tmpRate = 0;
			VecSDropItemCfg::const_iterator iterItem = vecGroupItem.begin();
			for (; iterItem != vecGroupItem.end(); ++iterItem)
			{
				const SDropItemCfg &stItemCfg = (*iterItem);
				//概率衰减
				int32_t dropRate = stItemCfg.dropRate;
				dropRate = (int32_t)(dropRate * ( (float)itemReduce / (float)DROP_RAND_BASE_NUM));
				//
				tmpRate += dropRate;
				if (randRate <= tmpRate)
				{
					if (stItemCfg.dropMaxNum > 0)
					{
						int32_t randNum = Random(stItemCfg.dropMinNum, stItemCfg.dropMaxNum);
						if (randNum > 0)
						{
							SItem item;
							item.nItemID = stItemCfg.itemId;
							item.nNum = randNum;
							lstItem.push_back(item);
							break;
						}
					} // end of if (stItemCfg.dropMaxNum > 0)

				} // end of if (randRate <= tmpRate)
			} // end of for (; iterItem != stGroupItem.vecDropItem.end(); ++iterItem)
		}
	}

	//
	CreateItem(lstItem, vecProtoEx, itemCond);

	//随机金币
	VEC_UINT32 vecGold;
	vecGold.clear();
	if (pDropCfg->gold_rand > 0)
	{
		int32_t randNum = Random(DROP_RAND_BASE_NUM + 1); // 0 - DROP_RAND_BASE_NUM;
		//LogDebugFmtPrint("[logic] DropMgr...gold...randnum:%d, gold_rand:%d ", randNum, pDropCfg->gold_rand);
		if (randNum <= pDropCfg->gold_rand)
		{
			//随机金币总数量
			int32_t totalDropGold = Random(pDropCfg->goldlow, pDropCfg->goldup);
			//金币衰减
			totalDropGold = (int32_t)(totalDropGold * ((float)goldReduce / (float)DROP_RAND_BASE_NUM));
			if (totalDropGold > 0)
			{
				int32_t totalPile = Random(pDropCfg->gold_heapMin, pDropCfg->gold_heapMax);
				if (totalPile > 0)
				{
					//金币数量小于堆数，堆数置成和金币一样的
					if (totalDropGold < totalPile)
					{
						totalPile = totalDropGold;
					}
					//
					//每一堆最小数量为 1
					totalDropGold -= totalPile;
					//再平均分配到每一堆
					int32_t averageNum = 0;
					if (totalDropGold > 0)
					{
						averageNum = totalDropGold / totalPile;
					}
					//剩余金币数量
					totalDropGold -= (averageNum * totalPile);
					vecGold.resize(totalPile, 1 + averageNum);
					//如果还有剩余，则随机分配到每一堆中
					if (totalDropGold > 0)
					{
						for (int32_t i = 0; i < totalPile - 1; ++i)
						{
							int32_t randPile = Random(1, totalDropGold);
							vecGold[i] += (uint32_t)randPile;
							if (randPile >= totalDropGold)
							{
								totalDropGold = 0;
								break;
							}
							else
							{
								totalDropGold -= randPile;
							}
						}
						//还有剩余，加在最后一堆里
						if (totalDropGold > 0)
						{
							vecGold[totalPile - 1] += totalDropGold;
						}
					} // end of if (totalDropGold > 0)
				} // end of if (totalPile > 0)
			} // end of if (totalDropGold > 0)
		} // end of if (randNum <= pDropCfg->gold_rand)		
	}
	VEC_UINT32::iterator iterGold = vecGold.begin();
	for (; iterGold != vecGold.end(); ++iterGold)
	{
		vecDropGold.push_back((*iterGold));
	}

	return true;
}

//创建宝箱掉落物品
bool ItemMgr::CreateBoxDropItem(uint32_t nBoxID, VEC_ITEM_PROTO_EX &vecProtoEx, int32_t &goldNum, int32_t &diamondNum, int32_t &bindDiamond, BoxCondCfg &boxCond, int32_t nNum /*= 1*/, bool bMerge /*= true*/)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	if (!BoxDropItem(nBoxID, lstItem, goldNum, diamondNum, bindDiamond, boxCond,nNum))
	{
		return false;
	}
	if (lstItem.size() > 0)
	{
		SItemCond itemCond;
		itemCond.level = boxCond.nLevel;
		itemCond.camp = boxCond.camp;
		CreateItem(lstItem, vecProtoEx, itemCond, bMerge);
	}

	return true;
}
//创建宝箱掉落物品
bool ItemMgr::CreateBoxDropItem(uint32_t nBoxID, LIST_ITEM &lstItem, int32_t &goldNum, int32_t &diamondNum, int32_t &bindDiamond, BoxCondCfg &boxCond, int32_t nNum /*= 1*/)
{
	return BoxDropItem(nBoxID, lstItem, goldNum, diamondNum, bindDiamond,boxCond, nNum);
}

bool ItemMgr::ZhuanPanDropItem(uint32_t nBoxID, LIST_UINT32& lstGrid, LIST_ITEM &lstItem, int32_t nNum)
{
	const BoxDropCfgInfo *pDropCfg = g_GetBoxDropCfgTable()->GetBoxDropCfgInfo(nBoxID);
	if (nullptr == pDropCfg)
	{
		LogErrFmtPrint("[logic] ZhuanPanDropItem nullptr == pDropCfg....boxdropid:%u ", nBoxID);
		return false;
	}
	//校验条件，从前往后，直到找到第一个满足条件的
	int32_t boxSonId = 0;
	VecBoxDropSonCfg::const_iterator iterCond = pDropCfg->vecBoxDropSonCfg.begin();
	for (; iterCond != pDropCfg->vecBoxDropSonCfg.end(); ++iterCond)
	{
		const BoxDropSonCfgInfo &cond = (*iterCond);
		if (cond.Id <= 0)
		{
			continue;
		}
		//
		boxSonId = cond.Id;
		break;
	}
	if (boxSonId <= 0)
	{
		return true;
	}
	const BoxSonCfgInfo *pBoxSonCfg = g_GetBoxSonCfgTable()->GetBoxSonCfgInfo(boxSonId);
	if (nullptr == pBoxSonCfg)
	{
		LogErrFmtPrint("[logic] BoxDropItem nullptr == pBoxSonCfg....boxSonId:%u ", boxSonId);
		return false;
	}

	if (pBoxSonCfg->drop_type != (int32_t)EBoxDropType::EBoxDropType_Weight
		&& pBoxSonCfg->drop_type != (int32_t)EBoxDropType::EBoxDropType_Dependence
		)
	{
		return false;
	}

	//随机物品
	for (int32_t icount = 0; icount < nNum; ++icount)
	{
		//if (pDropCfg->drop_type == (int32_t)EBoxDropType::EBoxDropType_Weight)
		{
			//统计总权重
			int32_t nTotalWeight = 0;
			const VecSBoxItemGroupCfg *pVecSBoxItemGroupCfg = g_GetDropCfgMgr()->GetBoxItemGroupCfg(boxSonId);
			if (nullptr != pVecSBoxItemGroupCfg)
			{
				VecSBoxItemGroupCfg::const_iterator iter = pVecSBoxItemGroupCfg->begin();
				for (; iter != pVecSBoxItemGroupCfg->end(); ++iter)
				{
					const SBoxItemGroup &boxItemGroup = (*iter);
					nTotalWeight += boxItemGroup.totalRate;
				}
			}
			//随机权重
			int32_t nRandWeight = (int32_t)Random(nTotalWeight);

			{
				int gridIndex = 0;
				int32_t nTempWeight = 0;
				//随机物品组
				if (nullptr != pVecSBoxItemGroupCfg)
				{
					const SBoxItemGroup *pBoxItemGroup = nullptr;
					for(int i = 0; i < (int)pVecSBoxItemGroupCfg->size(); i++)
					{
						const SBoxItemGroup &boxItemGroup = (*pVecSBoxItemGroupCfg)[i];
						nTempWeight += boxItemGroup.totalRate;
						if (nRandWeight <= nTempWeight)
						{
							gridIndex = i;
							pBoxItemGroup = &boxItemGroup;
							break;
						}
					}

					if (nullptr != pBoxItemGroup)
					{
						//在从组内随机一个物品
						const SBoxItemCfg *pSBoxItemCfg = nullptr;
						int32_t itemRand = (int32_t)Random(pBoxItemGroup->totalRate + 1); // 0- pBoxItemGroup->totalRate
						int32_t itemWeight = 0;
						VecSBoxItemCfg::const_iterator iterItem = pBoxItemGroup->vecBoxItem.begin();
						for (; iterItem != pBoxItemGroup->vecBoxItem.end(); ++iterItem)
						{
							const SBoxItemCfg &boxItem = (*iterItem);
							itemWeight += boxItem.dropRate;
							if (itemRand <= itemWeight)
							{
								pSBoxItemCfg = &boxItem;
								break;
							}
						}
						if (nullptr != pSBoxItemCfg)
						{
							const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pSBoxItemCfg->itemId);
							if (nullptr == pItemCfg)
							{
								const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pSBoxItemCfg->itemId);
								if (nullptr == pEquipCfg)
								{
									LogErrFmtPrint("[logic] DropMgr::BoxDropItem...nullptr==pEquipCfg .... boxid:%u , itemid:%u ", nBoxID, pSBoxItemCfg->itemId);
									return false;
								}
							}
							//随机物品数量
							int32_t nRandNum = (int32_t)Random(pSBoxItemCfg->dropMinNum, pSBoxItemCfg->dropMaxNum);
							if (nRandNum <= 0)
							{
								LogErrFmtPrint("[logic] BoxDropItem rand drop item num failed...itemid:%u ,nRandNum:%d, minnum:%d, maxnum:%d ", pSBoxItemCfg->itemId, nRandNum, pSBoxItemCfg->dropMinNum, pSBoxItemCfg->dropMaxNum);
								return true;
							}
							//LogDebugFmtPrint("[logic] CreateBoxDropItem 11....itemid:%u , num:%u ",pRandDropCfg->id,nRandNum);
							if (nullptr != pItemCfg)
							{
								//int32_t stackLimit = (pItemCfg->stackLimit <= 1) ? 1 : pItemCfg->stackLimit;
								SItem item;
								item.nItemID = pSBoxItemCfg->itemId;
								item.nNum = nRandNum;
								item.byBind = pSBoxItemCfg->byBind;
								lstGrid.push_back(gridIndex);
								lstItem.push_back(item);
							}
						}
						else
						{
							LogErrFmtPrint("[logic] ZhuanPanDropItem rand drop item failed....nTotalWeight:%d ,itemRand:%d ", pBoxItemGroup->totalRate, itemRand);
						} // end of if (nullptr != pSBoxItemCfg)
					} // end of if (nullptr != pBoxItemGroup)
				} // end of if (nullptr != pVecSBoxItemGroupCfg)


			} // end of if (nRandWeight <= pDropCfg->goldrand)
		}
	}
	return true;
}

//根据条件获取宝箱掉落的子ID
bool ItemMgr::GetBoxSonIdByCond(uint32_t nBoxID, BoxCondCfg &boxCond, int32_t &boxSonId)
{
	const BoxDropCfgInfo *pDropCfg = g_GetBoxDropCfgTable()->GetBoxDropCfgInfo(nBoxID);
	if (nullptr == pDropCfg)
	{
		LogErrFmtPrint("[logic] GetBoxSonIdByCond nullptr == pDropCfg....boxid:%u ", nBoxID);
		return false;
	}
	//校验条件，从前往后，直到找到第一个满足条件的
	VecBoxDropSonCfg::const_iterator iterCond = pDropCfg->vecBoxDropSonCfg.begin();
	for (; iterCond != pDropCfg->vecBoxDropSonCfg.end(); ++iterCond)
	{
		const BoxDropSonCfgInfo &cond = (*iterCond);
		if (cond.Id <= 0)
		{
			continue;
		}
		//性别
		if (BOX_COMMON_COND != cond.Sex && boxCond.bySex != cond.Sex)
		{
			continue;
		}
		//职业
		if (BOX_COMMON_COND != cond.profession && boxCond.byProf != cond.profession)
		{
			continue;
		}
		//最小等级
		if (BOX_COMMON_COND != cond.minlv && boxCond.nLevel < cond.minlv)
		{
			continue;
		}
		//最大等级
		if (BOX_COMMON_COND != cond.maxlv && boxCond.nLevel > cond.maxlv)
		{
			continue;
		}
		//
		boxSonId = cond.Id;
		break;
	}
	return true;
}

//宝箱子掉落物品
bool ItemMgr::BoxSonDropItem(uint32_t nBoxSonID, LIST_ITEM &lstItem, int32_t &goldNum, int32_t &diamondNum, int32_t &bindDiamond, int32_t nNum /*= 1*/)
{
	const BoxSonCfgInfo *pBoxSonCfg = g_GetBoxSonCfgTable()->GetBoxSonCfgInfo(nBoxSonID);
	if (nullptr == pBoxSonCfg)
	{
		LogErrFmtPrint("[logic] BoxDropItem nullptr == BoxSonDropItem....boxSonId:%u ", nBoxSonID);
		return false;
	}
	if (pBoxSonCfg->drop_type != (int32_t)EBoxDropType::EBoxDropType_Weight
		&& pBoxSonCfg->drop_type != (int32_t)EBoxDropType::EBoxDropType_Dependence
		)
	{
		return false;
	}
	//随机物品
	for (int32_t icount = 0; icount < nNum; ++icount)
	{
		if (pBoxSonCfg->drop_type == (int32_t)EBoxDropType::EBoxDropType_Weight)
		{
			//统计总权重
			int32_t nTotalWeight = 0;
			nTotalWeight += pBoxSonCfg->goldrand;
			nTotalWeight += pBoxSonCfg->jewelrand;
			nTotalWeight += pBoxSonCfg->bindjewelrand;
			const VecSBoxItemGroupCfg *pVecSBoxItemGroupCfg = g_GetDropCfgMgr()->GetBoxItemGroupCfg(nBoxSonID);
			if (nullptr != pVecSBoxItemGroupCfg)
			{
				VecSBoxItemGroupCfg::const_iterator iter = pVecSBoxItemGroupCfg->begin();
				for (; iter != pVecSBoxItemGroupCfg->end(); ++iter)
				{
					const SBoxItemGroup &boxItemGroup = (*iter);
					nTotalWeight += boxItemGroup.totalRate;
				}
			}
			//随机权重
			int32_t nRandWeight = (int32_t)Random(nTotalWeight);
			//先检查金币和钻石
			if (nRandWeight <= pBoxSonCfg->goldrand)
			{
				//金币
				goldNum += (int32_t)Random(pBoxSonCfg->goldminNum, pBoxSonCfg->goldmaxNum);
			}
			else if (nRandWeight <= (pBoxSonCfg->goldrand + pBoxSonCfg->bindjewelrand))
			{
				//绑定钻石
				bindDiamond += (int32_t)Random(pBoxSonCfg->bindjewelminNum, pBoxSonCfg->bindjewelmaxNum);
			}
			else if (nRandWeight <= (pBoxSonCfg->jewelrand + pBoxSonCfg->bindjewelrand + pBoxSonCfg->goldrand))
			{
				//钻石
				diamondNum += (int32_t)Random(pBoxSonCfg->jewelminNum, pBoxSonCfg->jewelmaxNum);
			}
			else
			{
				int32_t nTempWeight = pBoxSonCfg->jewelrand + pBoxSonCfg->bindjewelrand + pBoxSonCfg->goldrand;
				//随机物品组
				if (nullptr != pVecSBoxItemGroupCfg)
				{
					const SBoxItemGroup *pBoxItemGroup = nullptr;
					VecSBoxItemGroupCfg::const_iterator iterRand = pVecSBoxItemGroupCfg->begin();
					for (; iterRand != pVecSBoxItemGroupCfg->end(); ++iterRand)
					{
						const SBoxItemGroup &boxItemGroup = (*iterRand);
						nTempWeight += boxItemGroup.totalRate;
						if (nRandWeight <= nTempWeight)
						{
							pBoxItemGroup = &boxItemGroup;
							break;
						}
					}
					if (nullptr != pBoxItemGroup)
					{
						//在从组内随机一个物品
						const SBoxItemCfg *pSBoxItemCfg = nullptr;
						int32_t itemRand = (int32_t)Random(pBoxItemGroup->totalRate + 1); // 0- pBoxItemGroup->totalRate
						int32_t itemWeight = 0;
						VecSBoxItemCfg::const_iterator iterItem = pBoxItemGroup->vecBoxItem.begin();
						for (; iterItem != pBoxItemGroup->vecBoxItem.end(); ++iterItem)
						{
							const SBoxItemCfg &boxItem = (*iterItem);
							itemWeight += boxItem.dropRate;
							if (itemRand <= itemWeight)
							{
								pSBoxItemCfg = &boxItem;
								break;
							}
						}
						if (nullptr != pSBoxItemCfg)
						{
							const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pSBoxItemCfg->itemId);
							if (nullptr == pItemCfg)
							{
								const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pSBoxItemCfg->itemId);
								if (nullptr == pEquipCfg)
								{
									LogErrFmtPrint("[logic] DropMgr::BoxDropItem...nullptr==pEquipCfg .... boxid:%u , itemid:%u ", nBoxSonID, pSBoxItemCfg->itemId);
									return false;
								}
							}
							//随机物品数量
							int32_t nRandNum = (int32_t)Random(pSBoxItemCfg->dropMinNum, pSBoxItemCfg->dropMaxNum);
							if (nRandNum <= 0)
							{
								LogErrFmtPrint("[logic] BoxDropItem rand drop item num failed...itemid:%u ,nRandNum:%d, minnum:%d, maxnum:%d ", pSBoxItemCfg->itemId, nRandNum, pSBoxItemCfg->dropMinNum, pSBoxItemCfg->dropMaxNum);
								return true;
							}
							//LogDebugFmtPrint("[logic] CreateBoxDropItem 11....itemid:%u , num:%u ",pRandDropCfg->id,nRandNum);
							if (nullptr != pItemCfg)
							{
								//int32_t stackLimit = (pItemCfg->stackLimit <= 1) ? 1 : pItemCfg->stackLimit;
								SItem item;
								item.nItemID = pSBoxItemCfg->itemId;
								item.nNum = nRandNum;
								item.byBind = pSBoxItemCfg->byBind;
								lstItem.push_back(item);
							}
							else
							{
								//装备
								for (int32_t i = 0; i < nRandNum; ++i)
								{
									SItem item;
									item.nItemID = pSBoxItemCfg->itemId;
									item.nNum = 1;
									item.byBind = pSBoxItemCfg->byBind;
									lstItem.push_back(item);
								}
							}
						}
						else
						{
							LogErrFmtPrint("[logic] BoxDropItem rand drop item failed....nTotalWeight:%d ,itemRand:%d ", pBoxItemGroup->totalRate, itemRand);
						} // end of if (nullptr != pSBoxItemCfg)
					} // end of if (nullptr != pBoxItemGroup)
				} // end of if (nullptr != pVecSBoxItemGroupCfg)


			} // end of if (nRandWeight <= pDropCfg->goldrand)
		}
		else
		{
			//随机金币
			if ((uint32_t)pBoxSonCfg->goldrand > 0 && (Random(DROP_RAND_BASE_NUM) <= (uint32_t)pBoxSonCfg->goldrand))
			{
				goldNum += Random(pBoxSonCfg->goldminNum, pBoxSonCfg->goldmaxNum);
			}
			//随机绑定钻石
			if ((uint32_t)pBoxSonCfg->bindjewelrand > 0 && (Random(DROP_RAND_BASE_NUM) <= (uint32_t)pBoxSonCfg->bindjewelrand))
			{
				bindDiamond += Random(pBoxSonCfg->bindjewelminNum, pBoxSonCfg->bindjewelmaxNum);
			}
			//随机钻石
			if ((uint32_t)pBoxSonCfg->jewelrand > 0 && (Random(DROP_RAND_BASE_NUM) <= (uint32_t)pBoxSonCfg->jewelrand))
			{
				diamondNum += Random(pBoxSonCfg->jewelminNum, pBoxSonCfg->jewelmaxNum);
			}
			//每个物品组都随机一次
			const VecSBoxItemGroupCfg *pVecSBoxItemGroupCfg = g_GetDropCfgMgr()->GetBoxItemGroupCfg(nBoxSonID);
			if (nullptr != pVecSBoxItemGroupCfg)
			{
				VecSBoxItemGroupCfg::const_iterator iter = pVecSBoxItemGroupCfg->begin();
				for (; iter != pVecSBoxItemGroupCfg->end(); ++iter)
				{
					const SBoxItemGroup &boxItemGroup = (*iter);
					if (boxItemGroup.totalRate <= 0)
					{
						continue;
					}
					if (Random(DROP_RAND_BASE_NUM) <= (uint32_t)boxItemGroup.totalRate)
					{
						//物品组必掉一个物品
						const SBoxItemGroup *pBoxItemGroup = &boxItemGroup;
						const SBoxItemCfg *pSBoxItemCfg = nullptr;
						int32_t itemRand = Random(pBoxItemGroup->totalRate + 1); // 0- pBoxItemGroup->totalRate
						int32_t itemWeight = 0;
						VecSBoxItemCfg::const_iterator iterItem = pBoxItemGroup->vecBoxItem.begin();
						for (; iterItem != pBoxItemGroup->vecBoxItem.end(); ++iterItem)
						{
							const SBoxItemCfg &boxItem = (*iterItem);
							itemWeight += boxItem.dropRate;
							if (itemRand <= itemWeight)
							{
								pSBoxItemCfg = &boxItem;
								break;
							}
						}
						if (nullptr != pSBoxItemCfg)
						{
							const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pSBoxItemCfg->itemId);
							if (nullptr == pItemCfg)
							{
								const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pSBoxItemCfg->itemId);
								if (nullptr == pEquipCfg)
								{
									LogErrFmtPrint("[logic] DropMgr::BoxDropItem...nullptr==pEquipCfg 11 .... boxid:%u , itemid:%u ", nBoxSonID, pSBoxItemCfg->itemId);
									return false;
								}
							}
							//随机物品数量
							int32_t nRandNum = Random(pSBoxItemCfg->dropMinNum, pSBoxItemCfg->dropMaxNum);
							if (nRandNum <= 0)
							{
								LogErrFmtPrint("[logic] BoxDropItem rand drop item num failed 11...itemid:%u ,nRandNum:%d, minnum:%d, maxnum:%d ", pSBoxItemCfg->itemId, nRandNum, pSBoxItemCfg->dropMinNum, pSBoxItemCfg->dropMaxNum);
								return true;
							}
							//LogDebugFmtPrint("[logic] CreateBoxDropItem 11....itemid:%u , num:%u ",pRandDropCfg->id,nRandNum);
							if (nullptr != pItemCfg)
							{
								//int32_t stackLimit = (pItemCfg->stackLimit <= 1) ? 1 : pItemCfg->stackLimit;
								SItem item;
								item.nItemID = pSBoxItemCfg->itemId;
								item.nNum = nRandNum;
								item.byBind = pSBoxItemCfg->byBind;
								lstItem.push_back(item);
							}
							else
							{
								//装备
								for (int32_t i = 0; i < nRandNum; ++i)
								{
									SItem item;
									item.nItemID = pSBoxItemCfg->itemId;
									item.nNum = 1;
									item.byBind = pSBoxItemCfg->byBind;
									lstItem.push_back(item);
								}
							}
						}
						else
						{
							LogErrFmtPrint("[logic] BoxDropItem rand drop item failed 11....nTotalWeight:%d ,itemRand:%d ", pBoxItemGroup->totalRate, itemRand);
						} // end of if (nullptr != pSBoxItemCfg)

					} // end of if (Random(DROP_RAND_BASE_NUM) <= boxItemGroup.totalRate)
				} // end of for (; iter != pVecSBoxItemGroupCfg->end(); ++iter)
			} // end of if (nullptr != pVecSBoxItemGroupCfg)
		}
	} // end of for (int32_t icount = 0; icount < nNum; ++icount)

	return true;
}
//宝箱物品
bool ItemMgr::BoxDropItem(uint32_t nBoxID, LIST_ITEM &lstItem, int32_t &goldNum, int32_t &diamondNum, int32_t &bindDiamond, BoxCondCfg &boxCond, int32_t nNum /*= 1*/)
{
	int32_t boxSonId = 0;
	if (!GetBoxSonIdByCond(nBoxID, boxCond, boxSonId))
	{
		return false;
	}
	if (boxSonId <= 0)
	{
		return true;
	}
	return BoxSonDropItem(boxSonId, lstItem, goldNum, diamondNum, bindDiamond, nNum);
}

//创建宝箱子掉落物品 nBoxSonID:box表 son 表ID
bool ItemMgr::CreateBoxSonDropItem(uint32_t nBoxSonID, LIST_ITEM &lstItem, int32_t &goldNum, int32_t &diamondNum, int32_t &bindDiamond, int32_t nNum /*= 1*/)
{
	return BoxSonDropItem(nBoxSonID, lstItem, goldNum, diamondNum, bindDiamond, nNum);
}

//创建宝箱子掉落物品 nBoxSonID:box表 son 表ID
bool ItemMgr::CreateBoxSonDropItem(uint32_t nBoxSonID, VEC_ITEM_PROTO_EX &vecProtoEx, int32_t &goldNum, int32_t &diamondNum, int32_t &bindDiamond,int32_t nNum/* = 1*/, bool bMerge /*= true*/)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	if (!BoxSonDropItem(nBoxSonID, lstItem, goldNum, diamondNum, bindDiamond,nNum))
	{
		return false;
	}
	if (lstItem.size() > 0)
	{
		SItemCond itemCond;
		CreateItem(lstItem, vecProtoEx, itemCond, bMerge);
	}

	return true;
}

//设置出生装备信息
void ItemMgr::CreateCharEquip(CharacterDBInfo &req)
{
	CharacterDBEquipData *protoEquip = req.mutable_equipdata();
	if (nullptr == protoEquip)
	{
		MMOLOG_FMT_ERROR("ItemMgr::SetBornEquipProto...nullptr == protoEquip... ")
			return;
	}
	uint8_t byprof = (uint8_t)req.basedata().prof();
	uint8_t bysex = (uint8_t)req.basedata().sex();
	const RoleBornCfgInfo *pRoleBornCfg = g_GetRoleBornCfg(byprof, bysex);
	if (nullptr != pRoleBornCfg)
	{
		//武器
		SetBornEquipProto(EEquipPos_weapon, pRoleBornCfg->carryWeapons,protoEquip);
		//项链
		SetBornEquipProto(EEquipPos_necklace, pRoleBornCfg->carryNecklace,protoEquip);
		//披风
		SetBornEquipProto(EEquipPos_cloak, pRoleBornCfg->carryCloak, protoEquip);
		//衣服
		SetBornEquipProto(EEquipPos_clothes, pRoleBornCfg->carryArmor, protoEquip);
		//鞋子
		SetBornEquipProto(EEquipPos_boot, pRoleBornCfg->carryShoes, protoEquip);
		//护符
		SetBornEquipProto(EEquipPos_talisman, pRoleBornCfg->carryAmulet, protoEquip);
		//戒指
		SetBornEquipProto(EEquipPos_ring, pRoleBornCfg->carryRing1, protoEquip);
		SetBornEquipProto(EEquipPos_ring_ex, pRoleBornCfg->carryRing2, protoEquip);
		//护腕
		SetBornEquipProto(EEquipPos_bracer, pRoleBornCfg->carryBracer1, protoEquip);
		SetBornEquipProto(EEquipPos_bracer_ex, pRoleBornCfg->carryBracer2, protoEquip);
		//时装
		SetBornEquipProto(EEquipPos_fashion, pRoleBornCfg->carryFashionArmor, protoEquip);
		//翅膀
		SetBornEquipProto(EEquipPos_wing, pRoleBornCfg->carryWings, protoEquip);
	}
	else
	{
		MMOLOG_FMT_ERROR(" ItemMgr::CreateCharEquip nullptr == pRoleBornCfg....byprof:%u , bysex:%u ", byprof, bysex);
	}
}

bool ItemMgr::SetBornEquipProto(int8_t byPos, uint32_t nItemId, CharacterDBEquipData *protoEquip)
{

	if (byPos <= EEquipPos_none || byPos >= EEquipPos_limit || 0 == nItemId || nullptr == protoEquip)
	{
		return false;
	}

	const EquipEquipCfgInfo *pSEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemId);
	if (nullptr != pSEquipCfg)
	{
		if (EEquipPos_ring == pSEquipCfg->position)
		{
			if (byPos != EEquipPos_ring && byPos != EEquipPos_ring_ex)
			{
				return false;
			}
		}
		else if (EEquipPos_bracer == pSEquipCfg->position)
		{
			if (byPos != EEquipPos_bracer && byPos != EEquipPos_bracer_ex)
			{
				return false;
			}
		}
		else if (byPos != pSEquipCfg->position)
		{
			return false;
		}
		CItemBase *pNewEquip = g_GetItemMgr()->MakeItemObj(EItemType_equip);
		if (nullptr != pNewEquip)
		{
			int8_t byBind = g_GetItemMgr()->BindStateByDress(nItemId, (int8_t)EBindState::EBindState_no);//这里传非绑定参数主要是为了获取初始的绑定状态
			SItemCond itemCond;//初始装备，物品条件默认初始值
			if (pNewEquip->Init(byPos, nItemId, itemCond,1, byBind))
			{
				ItemProtoInfo *proto = protoEquip->add_equip();
				if (nullptr != proto)
				{
					SetItemProtoInfo(pNewEquip, proto);
				}
			}
			g_GetItemMgr()->FreeItemObj(pNewEquip);
		}
	}
	return false;

}


//设置物品信息
bool ItemMgr::SetItemProtoInfo(LIST_ITEM &lstItem, VEC_ITEM_PROTO_EX &vecProto, SItemCond &itemCond)
{
	return CreateItem(lstItem, vecProto, itemCond);
}

bool ItemMgr::SetItemProtoInfo(CItemBase *pItem, ItemProtoInfo *protoItemInfo, int32_t nNum /*= -1*/)
{
	if (nullptr == pItem || nullptr == protoItemInfo)
	{
		return false;
	}
	protoItemInfo->set_index(pItem->GetIndex());
	protoItemInfo->set_item_id(pItem->GetItemID());
	if (0 == nNum)
	{
		protoItemInfo->set_item_num(0);
	}
	else if (nNum > 0)
	{
		if ((uint32_t)nNum > pItem->GetNum())
		{
			protoItemInfo->set_item_num(pItem->GetNum());
		}
		else
		{
			protoItemInfo->set_item_num(nNum);
		}
	}
	else
	{
		//默认为小于0，这时候取传入物品参数pItem的数量
		protoItemInfo->set_item_num(pItem->GetNum());
	}

	//
	protoItemInfo->set_bind(pItem->GetBind());
	protoItemInfo->set_maker(pItem->GetMaker());
	protoItemInfo->set_areaid(pItem->GetAreaId());
	protoItemInfo->set_active(pItem->ActiveStatus());
	protoItemInfo->set_fund(pItem->GetFund());
	protoItemInfo->set_ave_price(pItem->GetAvePrice());
	protoItemInfo->set_hpmp_value(pItem->GetHpMpValue());

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
	if (pItem->GetMarkPos() && pItemCfg && (pItemCfg->subType == (int32_t)EItemSubType::EItemSubType_star_soul_paper || pItemCfg->subType == (int32_t)EItemSubType::EItemSubType_star_soul_reel))
	{
		StarSoulProto *soul = protoItemInfo->mutable_soul();
		size_t size = pItem->GetMarkPos()->size();
		for (size_t i = 0; i < size; i++)
		{
			ItemMarkPos *mPos = soul->add_mark_list();
			if (nullptr == mPos)	continue;
			mPos->set_map_id(pItem->GetMarkPos()->at(i).mapId);
			Vector3PB *pos = mPos->mutable_pos();
			if (nullptr == pos)	continue;
			pos->set_x(pItem->GetMarkPos()->at(i).pos.x);
			pos->set_y(pItem->GetMarkPos()->at(i).pos.y);
			pos->set_z(pItem->GetMarkPos()->at(i).pos.z);
		}
		soul->set_confing_times(pItem->GetConfigTimes());
		soul->set_use_times(pItem->GetUseTimes());
	}

	if (EItemType_equip == pItem->GetType())
	{
		protoItemInfo->set_identify(pItem->Identify());
		protoItemInfo->set_refinelv(pItem->GetRefineLev());
		protoItemInfo->set_holy(pItem->GetHoly());
		protoItemInfo->set_add_by_deputy(pItem->AddByDeputy());
		protoItemInfo->set_end_tick(pItem->GetEndTick());

		//基础属性
		MAP_INT32_INT32 *pBaseMap = pItem->GetBaseAttr();
		if (nullptr != pBaseMap)
		{
			MAP_INT32_INT32::iterator iter = pBaseMap->begin();
			for (; iter != pBaseMap->end(); ++iter)
			{
				Attr *protoAttr = protoItemInfo->add_baseattr();
				if (nullptr != protoAttr)
				{
					protoAttr->set_attrnum(iter->first);
					protoAttr->set_attrvalue(iter->second);
				}
			}
		}

		//精炼额外属性
		MAP_INT32_INT32 *pExMap = pItem->GetRefineEx();
		if (nullptr != pExMap)
		{
			MAP_INT32_INT32::iterator iter = pExMap->begin();
			for (; iter != pExMap->end(); ++iter)
			{
				Attr *protoAttr = protoItemInfo->add_refineex();
				if (nullptr != protoAttr)
				{
					protoAttr->set_attrnum(iter->first);
					protoAttr->set_attrvalue(iter->second);
				}
			}
		}

		//镶嵌宝石
		VEC_UINT32 *inlayList = pItem->GetInlay();
		if (inlayList && inlayList->size() > 0)
		{
			for (uint16_t i = 0; i < inlayList->size(); ++i)
			{
				protoItemInfo->add_inlay(inlayList->at(i));
			}
		}
		
	} // end of if (EPackageLabel_equip == pItem->GetType())

	return true;
}

//是否有效的绑定途径
bool ItemMgr::ValidBindWay(int8_t bindWay)
{
	if (bindWay > EItemBindWay_None && bindWay < EItemBindWay_Limit)
	{
		return true;
	}
	return false;
}

//是否有效的禁止类型
bool ItemMgr::ValidForbidType(int8_t forbidType)
{
	if (forbidType > EItemForbidType_None && forbidType < EItemForbidType_Limit)
	{
		return true;
	}
	return false;
}
//是否有效的物品属性初始化类型
bool ItemMgr::ValidInitAttrType(int8_t initAttrType)
{
	if (initAttrType > EItemInitAttrType_None && initAttrType < EItemInitAttrType_Limit)
	{
		return true;
	}
	return false;
}

//物品是否能交易
bool ItemMgr::CanTrade(uint32_t itemId, int8_t byInBind)
{
	/*
	已绑定状态
		禁止拍卖，禁止作为邮件附件
		允许PK死亡掉落
		已绑定状态的物品/装备，角色死亡，掉落物直接销毁
		掉落文字提示内容：“本次死亡不幸摧毁XXXX”，XXXX为物品/装备名
		文字显示在聊天框系统记录频道
		允许出售
	未绑定状态
		允许拍卖，允许作为邮件附件
		允许PK死亡掉落，掉落出掉落物
		允许出售
	*/

	int8_t forbidType = EItemForbidType_None;
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemId);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(itemId);
		if (nullptr == pEquipCfg)
		{
			//LogErrFmtPrint("[logic] CanSell ....nullptr == pEquipCfg, itemid:%u ", nItemId);
			//如果找不到配置信息，默认返回不能交易
			return false;
		}
		forbidType = pEquipCfg->tradeControl;
	}
	else
	{
		forbidType = pItemCfg->tradeControl;
	}
	if (forbidType == EItemForbidType_Forbid)//禁止交易
	{
		return false;
	}
	if (byInBind == (int8_t)EBindState::EBindState_bind) //已绑定状态 禁止拍卖，禁止作为邮件附件
	{
		return false;
	}

	//未绑定状态 允许拍卖，允许作为邮件附件
	return true;
}
//物品能否出售
bool ItemMgr::CanSell(uint32_t itemId, int8_t byInBind)
{
	/*
	已绑定状态
		禁止拍卖，禁止作为邮件附件
		允许PK死亡掉落
		已绑定状态的物品/装备，角色死亡，掉落物直接销毁
		掉落文字提示内容：“本次死亡不幸摧毁XXXX”，XXXX为物品/装备名
		文字显示在聊天框系统记录频道
		允许出售
	未绑定状态
		允许拍卖，允许作为邮件附件
		允许PK死亡掉落，掉落出掉落物
		允许出售
	*/
	_UNUSE(byInBind);
	int8_t forbidType = EItemForbidType_None;
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemId);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(itemId);
		if (nullptr == pEquipCfg)
		{
			//LogErrFmtPrint("[logic] CanSell ....nullptr == pEquipCfg, itemid:%u ", nItemId);
			//如果找不到配置信息，默认返回不能出售
			return false;
		}
		forbidType = pEquipCfg->sellControl;
	}
	else
	{
		forbidType = pItemCfg->sellControl;
	}
	if (forbidType == EItemForbidType_Forbid)//禁止出售
	{
		return false;
	}
	
	//已绑定状态 允许出售, 未绑定状态，允许出售
	return true;
}

//物品能否死亡掉落  byDestory:是否掉落直接销毁
bool ItemMgr::CanDieDrop(uint32_t itemId, int8_t byInBind)
{
	/*
	已绑定状态
		禁止拍卖，禁止作为邮件附件
		(去掉了)允许PK死亡掉落
		(去掉了)已绑定状态的物品/装备，角色死亡，掉落物直接销毁
		(去掉了)掉落文字提示内容：“本次死亡不幸摧毁XXXX”，XXXX为物品/装备名
		(去掉了)文字显示在聊天框系统记录频道
		禁止死亡掉落 PVE死亡、PVP死亡都不掉落
		允许出售
	未绑定状态
		允许拍卖，允许作为邮件附件
		允许PK死亡掉落，掉落出掉落物
		允许出售

	*/
	int8_t forbidType = EItemForbidType_None;
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemId);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(itemId);
		if (nullptr == pEquipCfg)
		{
			return false;
		}
		forbidType = pEquipCfg->dropControl;
	}
	else
	{
		forbidType = pItemCfg->dropControl;
	}

	if (forbidType == EItemForbidType_Forbid)//禁止死亡掉落
	{
		return false;
	}

	if (byInBind == (int8_t)EBindState::EBindState_bind) 
	{
		//已绑定状态 禁止死亡掉落 PVE死亡、PVP死亡都不掉落
		return false;
	}
	
	return true;
}

//获取背包标签页
uint8_t ItemMgr::GetPackageLabel(uint32_t nItemId)
{
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nItemId);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemId);
		return GetPackageLabel(pEquipCfg);
	}
	return GetPackageLabel(pItemCfg);
}
uint8_t ItemMgr::GetPackageLabel(const ItemItemCfgInfo *pItemCfg)
{
	if (nullptr == pItemCfg)
	{
		return EPackageLabel_none;
	}
	if (EPackageLabel_task == pItemCfg->itemType)
	{
		return EPackageLabel_task;
	}
	return EPackageLabel_all;
	
}
uint8_t ItemMgr::GetPackageLabel(const EquipEquipCfgInfo *pEquipCfg)
{
	if (nullptr == pEquipCfg)
	{
		return EPackageLabel_none;
	}
	return EPackageLabel_all;
}
//是否是任务物品
bool ItemMgr::IsTaskItem(uint32_t itemId)
{
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemId);
	if (nullptr != pItemCfg && EPackageLabel_task == pItemCfg->itemType)
	{
		return true;
	}
	return false;
}
//背包添加物品后物品的绑定状态
int8_t ItemMgr::BindStateByAdd(uint32_t nItemId, int8_t byBind)
{
	//非绑定状态才需要默认绑定规则处理
	if ((int8_t)EBindState::EBindState_bind == byBind)
	{
		return byBind;
	}
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nItemId);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemId);
		if (nullptr == pEquipCfg)
		{
			//物品不存在的时候直接返回 -1
			return -1;
		}
		return BindStateByAdd(pEquipCfg, byBind);
	}
	return BindStateByAdd(pItemCfg, byBind);

}
//背包添加物品后物品的绑定状态
int8_t ItemMgr::BindStateByAdd(const ItemItemCfgInfo *pItemCfg, int8_t byBind)
{
	if (nullptr == pItemCfg)
	{
		return -1;
	}
	//非绑定状态才需要默认绑定规则处理
	if ((int8_t)EBindState::EBindState_bind == byBind)
	{
		return byBind;
	}
	int8_t byBindEx = (int8_t)EBindState::EBindState_no;
	if (EItemBindWay_Bind == pItemCfg->bindType
		|| EItemBindWay_Get == pItemCfg->bindType)//永久绑定和获取绑定两种类型的物品 进入背包是绑定状态
	{
		byBindEx = (int8_t)EBindState::EBindState_bind;
	}

	return byBindEx;
}
//背包添加物品后物品的绑定状态
int8_t ItemMgr::BindStateByAdd(const EquipEquipCfgInfo *pEquipCfg, int8_t byBind)
{
	if (nullptr == pEquipCfg)
	{
		return -1;
	}
	//非绑定状态才需要默认绑定规则处理
	if ((int8_t)EBindState::EBindState_bind == byBind)
	{
		return byBind;
	}
	int8_t byBindEx = (int8_t)EBindState::EBindState_no;
	if (EItemBindWay_Bind == pEquipCfg->bindType
		|| EItemBindWay_Get == pEquipCfg->bindType)//永久绑定和获取绑定两种类型的物品 进入背包是绑定状态
	{
		byBindEx = (int8_t)EBindState::EBindState_bind;
	}

	return byBindEx;
}



//穿戴装备后装备的绑定状态
int8_t ItemMgr::BindStateByDress(uint32_t nItemId, int8_t byBind)
{
	if ((int8_t)EBindState::EBindState_bind == byBind) //非绑定才需要默认规则处理
	{
		return byBind;
	}
	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemId);
	return BindStateByDress(pEquipCfg,byBind);
}

int8_t ItemMgr::BindStateByDress(const EquipEquipCfgInfo *pEquipCfg, int8_t byBind)
{
	if ((int8_t)EBindState::EBindState_bind == byBind) //非绑定才需要默认规则处理
	{
		return byBind;
	}
	if (nullptr != pEquipCfg && EItemBindWay_Dress == pEquipCfg->bindType) //穿戴绑定
	{
		return (int8_t)EBindState::EBindState_bind;
	}
	return (int8_t)EBindState::EBindState_no;
}

//获取物品堆叠数
int32_t ItemMgr::ItemMaxPile(uint32_t itemId)
{
	int32_t maxPile = 0;
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemId);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(itemId);
		maxPile = ItemMaxPile(pEquipCfg);
	}
	else
	{
		maxPile = ItemMaxPile(pItemCfg);
	}
	return maxPile;
}
//获取物品堆叠数
int32_t ItemMgr::ItemMaxPile(const ItemItemCfgInfo *pItemCfg)
{
	int32_t maxPile = 0;
	if (nullptr != pItemCfg)
	{
		maxPile = (pItemCfg->stackLimit < 1) ? 1 : pItemCfg->stackLimit;
	}
	return maxPile;
}
//获取物品堆叠数
int32_t ItemMgr::ItemMaxPile(const EquipEquipCfgInfo *pEquipCfg)
{
	int32_t maxPile = 0;
	if (nullptr != pEquipCfg)
	{
		maxPile = 1;//装备默认为1
	}
	return maxPile;
}

uint32_t ItemMgr::GetOpenLel(uint32_t constant_id)
{
	MAP_INT32_INT32::iterator it = m_openLelMap.find(constant_id);
	return (it == m_openLelMap.end()) ? 0xff : it->second;
}

//校验物品
bool ItemMgr::CheckItem(VEC_ITEM_PROTO_EX &vecProtoItems)
{
	VEC_ITEM_PROTO_EX::iterator iter = vecProtoItems.begin();
	for (; iter != vecProtoItems.end(); ++iter)
	{
		ItemProtoInfo &proto = (*iter);
		if (!proto.has_item_id() || !proto.has_item_num() || (proto.item_num() < 0))
		{
			return false;
		}
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(proto.item_id());
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(proto.item_id());
			if (nullptr == pEquipCfg)
			{
				return false;
			}
			if (proto.item_num() != 1)//装备的数量必须为1
			{
				return false;
			}
		}
	}
	return true;
}
//合并物品
void ItemMgr::MergeItem(LIST_ITEM &lstItem, LIST_ITEM &lstOutItem)
{
	LIST_ITEM::iterator iter = lstItem.begin();
	for (; iter != lstItem.end(); ++iter)
	{
		SItem &item = (*iter);
		if (item.nItemID == 0)
		{
			continue;
		}
		int32_t stackLimit = 1;
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(item.nItemID);
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(item.nItemID);
			if (nullptr == pEquipCfg)
			{
				continue;
			}
			stackLimit = ItemMaxPile(pEquipCfg);
		}
		else
		{
			stackLimit = ItemMaxPile(pItemCfg);
		}

		int32_t nCount = item.nNum;
		LIST_ITEM::iterator iterout = lstOutItem.begin();
		for (; iterout != lstOutItem.end(); ++iterout)
		{
			SItem &itemout = (*iterout);
			if (itemout.nItemID == item.nItemID
				&& itemout.byBind == item.byBind
				&& itemout.nNum < stackLimit
				)
			{
				int32_t nCanAdd = stackLimit - itemout.nNum;
				if (nCount <= nCanAdd)
				{
					itemout.nNum += nCount;
					nCount = 0;
				}
				else
				{
					itemout.nNum += nCanAdd;
					nCount -= nCanAdd;
				}
			}
		}
		//
		if (nCount > 0)
		{
			uint16_t nCnt = nCount / stackLimit;
			uint16_t nExt = nCount % stackLimit;
			uint16_t nMaxPile = stackLimit;
			for (int32_t i = 0; i < nCnt; ++i)
			{
				SItem newitem;
				newitem.nItemID = item.nItemID;
				newitem.nNum = nMaxPile;
				newitem.byBind = item.byBind;
				lstOutItem.push_back(newitem);
			}
			if (nExt > 0)
			{
				SItem newitem;
				newitem.nItemID = item.nItemID;
				newitem.nNum = nExt;
				newitem.byBind = item.byBind;
				lstOutItem.push_back(newitem);
			}
			nCount = 0;
		}
	}
}